home *** CD-ROM | disk | FTP | other *** search
/ Aminet 15 / Aminet 15 - Nov 1996.iso / Aminet / dev / c / GroupBorderCla.lha / groupfra.c next >
C/C++ Source or Header  |  1995-11-09  |  8KB  |  316 lines

  1. /*
  2.  *    File:                    GroupFrameClass.c
  3.  *    Description:    Draws frames around groups of gadgets
  4.  *
  5.  *    (C) 1995, Ketil Hunn
  6.  *
  7.  */
  8.  
  9. /*** PRIVATE INCLUDES ****************************************************************/
  10. #include <exec/types.h>
  11. #include <intuition/intuition.h>
  12. #include <intuition/classes.h>
  13. #include <intuition/classusr.h>
  14. #include <intuition/imageclass.h>
  15. #include <intuition/gadgetclass.h>
  16. #include <intuition/cghooks.h>
  17. #include <intuition/icclass.h>
  18. #include <utility/tagitem.h>
  19. #include <utility/hooks.h>
  20. #include <graphics/rpattr.h>
  21. #include <graphics/gfxmacros.h>
  22. #include <dos.h>
  23.  
  24. #include <clib/exec_protos.h>
  25. #include <clib/intuition_protos.h>
  26. #include <clib/graphics_protos.h>
  27. #include <clib/utility_protos.h>
  28. #include <clib/alib_protos.h>
  29. #include <clib/alib_stdio_protos.h>
  30.  
  31. /*** DEFINES *************************************************************************/
  32. #define    TITLEGAP        4
  33.  
  34. #define    THICKFRAME    1
  35. #define    PLACELEFT        2
  36. #define    PLACERIGHT    4
  37. #define    HIGHLIGHT        8
  38. #define    SHADOW            16
  39.  
  40. /*** GLOBALS *************************************************************************/
  41. struct GroupFrameInst
  42. {
  43.     STRPTR                    title;
  44.     WORD                        underline;
  45.     struct TextFont    *font;
  46.     ULONG                        flags;
  47. };
  48.  
  49. /*** PROTOTYPES **********************************************************************/
  50. __asm WORD StrCpyC(    register __a0 UBYTE *dest,
  51.                                         register __a1 UBYTE *src);
  52. ULONG __asm dispatchGroupFrame(    register __a0 Class        *class,
  53.                                                                 register __a2 Object    *o,
  54.                                                                 register __a1 Msg            msg);
  55. __asm ULONG renderGroupFrame(    register __a0 Class                                    *class,
  56.                                                             register __a1 struct Gadget                    *g,
  57.                                                             register __a2 struct gpRender                *msg,
  58.                                                             register __a3 struct GroupFrameInst    *inst);
  59. /*** FUNCTIONS ***********************************************************************/
  60.  
  61. __asm Class *initGroupFrameClass(void)
  62. {
  63.     Class                    *class;
  64.  
  65.     if(class=MakeClass(NULL, GADGETCLASS, NULL, sizeof(struct GroupFrameInst), 0))
  66.     {
  67.         class->cl_Dispatcher.h_Entry        =(HOOKFUNC)dispatchGroupFrame;
  68.         class->cl_Dispatcher.h_SubEntry    =NULL;
  69.         class->cl_Dispatcher.h_Data            =(void *)getreg(REG_A4);
  70.     }
  71.     return class;
  72. }
  73.  
  74. ULONG __asm dispatchGroupFrame(    register __a0 Class        *class,
  75.                                                                 register __a2 Object    *o,
  76.                                                                 register __a1 Msg            msg)
  77. {
  78.     struct GroupFrameInst    *inst;
  79.     Object                                *object;
  80.     ULONG                                    retval=FALSE;
  81.  
  82.     putreg(REG_A4, (long)class->cl_Dispatcher.h_Data);
  83.     switch (msg->MethodID)
  84.     {
  85.         case OM_NEW:
  86.             if(object=(Object *)DoSuperMethodA(class, o, msg))
  87.             {
  88.                 struct TagItem                    *taglist=((struct opSet *)msg)->ops_AttrList,
  89.                                                                 *tstate=taglist;
  90.                 register struct TagItem    *tag;
  91.                 register STRPTR                    title=NULL;
  92.  
  93.                 if(inst=INST_DATA(class, object))
  94.                 {
  95.                     inst->underline    =-1;
  96.                     inst->title            =NULL;
  97.                     while(tag=NextTagItem(&tstate))
  98.                         switch(tag->ti_Tag)
  99.                         {
  100.                             case EG_Title:
  101.                             case GA_Text:
  102.                                 title=(STRPTR)tag->ti_Data;
  103.                                 break;
  104.                             case EG_Font:
  105.                                 inst->font=(struct TextFont *)tag->ti_Data;
  106.                                 break;
  107.                             case EG_ThickFrame:
  108.                                 IFTRUESETBIT(tag->ti_Data, inst->flags, THICKFRAME);
  109.                                 break;
  110.                             case EG_PlaceTitleLeft:
  111.                                 IFTRUESETBIT(tag->ti_Data, inst->flags, PLACELEFT);
  112.                                 break;
  113.                             case EG_PlaceTitleRight:
  114.                                 IFTRUESETBIT(tag->ti_Data, inst->flags, PLACERIGHT);
  115.                                 break;
  116.                             case EG_Highlight:
  117.                                 IFTRUESETBIT(tag->ti_Data, inst->flags, HIGHLIGHT);
  118.                                 break;
  119.                             case EG_Shadow:
  120.                                 IFTRUESETBIT(tag->ti_Data, inst->flags, SHADOW);
  121.                                 break;
  122.                         }
  123.                         if(title)
  124.                         {
  125.                             if(inst->title=(STRPTR)AllocVec(strlen(title), 0L))
  126.                                 inst->underline=StrCpyC(inst->title, title);
  127.                             else
  128.                             {
  129.                     CoerceMethod(class, o, OM_DISPOSE);
  130.                     object=NULL;
  131.                             }
  132.                         }
  133.                 }
  134.                 retval=(ULONG)object;
  135.             }
  136.             break;
  137.         case OM_DISPOSE:
  138.             if(inst=INST_DATA(class, o))
  139.                 if(inst->title)
  140.                     FreeVec(inst->title);
  141.             retval=DoSuperMethodA(class, o, msg);
  142.             break;
  143.         case GM_HITTEST:
  144.             retval=GMR_REUSE;
  145.             break;
  146.         case GM_GOACTIVE:
  147.             retval=GMR_NOREUSE;
  148.             break;
  149.         case GM_RENDER:
  150.             if(inst=INST_DATA(class, o))
  151.                 retval=renderGroupFrame(class, (struct Gadget *)o, (struct gpRender *)msg, inst);
  152.             break;
  153.         case GM_HANDLEINPUT:
  154.             retval=GMR_REUSE;
  155.             break;
  156.         default:
  157.             retval=DoSuperMethodA(class, o, msg);
  158.             break;
  159.     }
  160.     return retval;
  161. }
  162.  
  163. /*
  164. __asm WORD StrCpyC(    register __a0 UBYTE *dest,
  165.                                         register __a1 UBYTE *src)
  166. {
  167.     register UBYTE *start=src;
  168.     register WORD uline=-1;
  169.  
  170.     if(src)
  171.     {
  172.         while(*src)
  173.             if(*src=='_')
  174.                 uline=src++-start;
  175.             else
  176.                 *dest++=*src++;
  177.         *dest='\0';
  178.     }
  179.     return uline;
  180. }
  181. */
  182. __asm void UText(    register __a2 struct RastPort    *rp,
  183.                                     register __d0 WORD                        x,
  184.                                     register __d1 WORD                        y,
  185.                                     register __a1 UBYTE                     *text,
  186.                                     register __d2 WORD                        underline)
  187. {
  188.     Move(rp, x, y);
  189.     Text(rp, text, strlen(text));
  190.  
  191.     if(underline>-1)
  192.     {
  193.         Move(rp, x+=TextLength(rp, text, underline), ++y);
  194.         Draw(rp, x+TextLength(rp, text+underline, 1)-2, y);
  195.     }
  196. }
  197.  
  198. __asm void DrawBevel(    register __a0 struct RastPort    *rp,
  199.                                             register __a1 UWORD                        *pens,
  200.                                             register __a2    UBYTE                        thick,
  201.                                             register __d6    UBYTE                        raised,
  202.                                             register __d0 WORD                        x,
  203.                                             register __d1 WORD                        y,
  204.                                             register __d2 WORD                        w,
  205.                                             register __d3 WORD                        h,
  206.                                             register __d4 WORD                        titlegap,
  207.                                             register __d5 WORD                        titlegapwidth)
  208. {
  209.     SetAPen(rp, (raised ? pens[SHINEPEN]:pens[SHADOWPEN]));
  210.     Move(rp, x,        y+h-1);
  211.     Draw(rp, x,        y);
  212.  
  213.     if(thick)
  214.     {
  215.         Move(rp, x+1,        y+h-1);
  216.         Draw(rp, x+1,        y);
  217.     }
  218.  
  219.     if(titlegap>-1)
  220.     {
  221.         Draw(rp, titlegap , y);
  222.         Move(rp, titlegap+titlegapwidth, y);
  223.     }
  224.     Draw(rp, x+w-1,    y);
  225.  
  226.     SetAPen(rp, (raised ? pens[SHADOWPEN]:pens[SHINEPEN]));
  227.     Move(rp, x+w, y+1);
  228.     Draw(rp, x+w, y+h);
  229.  
  230.     if(thick)
  231.     {
  232.         Move(rp, x+w-1,        y+1);
  233.         Draw(rp, x+w-1,        y+h);
  234.     }
  235.  
  236.     Draw(rp, x+1, y+h);
  237. }
  238.  
  239. __asm ULONG renderGroupFrame(    register __a0 Class                                    *class,
  240.                                                             register __a1 struct Gadget                    *g,
  241.                                                             register __a2 struct gpRender                *msg,
  242.                                                             register __a3 struct GroupFrameInst    *inst)
  243. {
  244.     struct RastPort        *rp;
  245.     ULONG retval            =FALSE;
  246.     UWORD    *pens                =msg->gpr_GInfo->gi_DrInfo->dri_Pens;
  247.  
  248.     if(msg->MethodID==GM_RENDER)
  249.         rp=msg->gpr_RPort;
  250.     else
  251.         rp=ObtainGIRPort(msg->gpr_GInfo);
  252.  
  253.     if(rp && pens)
  254.     {
  255.         register UWORD    x=g->LeftEdge,
  256.                                         y=g->TopEdge,
  257.                                         w=g->Width-1,
  258.                                         h=g->Height-1,
  259.                                         titleleft    =-1,
  260.                                         titlewidth;
  261.         struct TextFont    *font=(inst->font==NULL ? rp->Font:inst->font);
  262.  
  263.         SetFont(rp, font);
  264.         if(ISBITSET(g->Flags, GFLG_RELRIGHT))
  265.             x+=msg->gpr_GInfo->gi_Domain.Width-1;
  266.  
  267.         if(inst->title)
  268.         {
  269.             titlewidth=TextLength(rp, inst->title, strlen(inst->title))-TITLEGAP/2;
  270.  
  271.             if(ISBITSET(inst->flags, PLACELEFT))
  272.                 titleleft=x+TITLEGAP*2;
  273.             else if(ISBITSET(inst->flags, PLACERIGHT))
  274.                 titleleft=x+w-TITLEGAP*2-titlewidth;
  275.             else
  276.                 titleleft=x+(w-titlewidth)/2;
  277.         }
  278.  
  279.         if(ISBITSET(inst->flags, THICKFRAME))
  280.         {
  281.             DrawBevel(rp, pens, TRUE, TRUE,  x+2, y+1, w-4, h-2, titleleft-TITLEGAP, titlewidth+TITLEGAP*2);
  282.             DrawBevel(rp, pens, TRUE, FALSE, x, y, w, h, titleleft-TITLEGAP, titlewidth+TITLEGAP*2);
  283.         }
  284.         else
  285.         {
  286.             DrawBevel(rp, pens, FALSE, TRUE,  x+1, y+1, w-2, h-2, titleleft-TITLEGAP, titlewidth+TITLEGAP*2);
  287.             DrawBevel(rp, pens, FALSE, FALSE, x, y, w, h, titleleft-TITLEGAP, titlewidth+TITLEGAP*2);
  288.         }
  289.  
  290.         if(inst->title)
  291.         {
  292.             register WORD ypos=y+font->tf_Baseline/2;
  293.  
  294.             SetDrMd(rp, JAM1);
  295.  
  296.             if(ISBITSET(inst->flags, SHADOW))
  297.             {
  298.                 SetAPen(rp, pens[SHADOWPEN]);
  299.                 UText(rp, titleleft, 1+ypos, inst->title, inst->underline);
  300.                 SetAPen(rp, pens[HIGHLIGHTTEXTPEN]);
  301.                 UText(rp, titleleft-1, ypos, inst->title, inst->underline);
  302.             }
  303.             else
  304.             {
  305.                 SetAPen(rp, (ISBITSET(inst->flags, HIGHLIGHT) ? pens[HIGHLIGHTTEXTPEN]:pens[TEXTPEN]));
  306.                 UText(rp, titleleft, ypos, inst->title, inst->underline);
  307.             }
  308.         }
  309.         retval=TRUE;
  310.     }
  311.     if(msg->MethodID!=GM_RENDER)
  312.         ReleaseGIRPort(rp);
  313.  
  314.     return retval;
  315. }
  316.